package yto.freemarker.java8.stream;

import org.junit.Test;
import yto.freemarker.java8.entity.Employee;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 终止的操作
 * collect
 * 查找匹配
 *
 * @author dongxing
 * @create 2018-06-23 14:26
 **/
public class TestStreamApi03 {
    List<Employee> list = Arrays.asList(new Employee("Zhansgan", 10, 200.0, Employee.Status.FREE),
            new Employee("lisi", 20, 300.0, Employee.Status.BUSY),
            new Employee("wangwu", 30, 400.0, Employee.Status.VOCATION),
            new Employee("zhangliu", 40, 500.0, Employee.Status.BUSY)
    );

    /**
     * 查找与匹配
     * <p>
     * allmatch ---检查所有元素是否匹配
     * anymatch---检查是否至少一个元素匹配
     * nonematch---检查是否没有元素匹配
     * findfirst  ---查找第一个
     * findAny   ---返回当前元素中的任意一个
     * count ---返回元素中的总个数
     * max  ----返回中的最大
     * min  ---返回中的最小
     */
    @Test
    public void test1() {

        boolean b = list.stream()
                .allMatch((employee) -> employee.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b);
        System.out.println("-----------------------");

        boolean b1 = list.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);
        System.out.println("-------------------");

        boolean b2 = list.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        System.out.println("-----------------------");

        Optional<Employee> optional = list.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSolary(), e2.getSolary()))
                .findFirst();
        System.out.println(optional.get());
        System.out.println("-----------------------------");

        Optional<Employee> optional1 = list.stream()
                .filter((e) -> e.getAge() > 10)
                .findAny();
        System.out.println(optional1.get());
    }


    @Test
    public void test2() {
        long count = list.stream()
                .count();
        System.out.println(count);
        System.out.println("------------------------");

        Optional<Employee> max = list.stream()
                .max((e1, e2) -> e1.getAge().compareTo(e2.getAge()));
        //如果为空，则替换为括号中的值
        max.orElse(new Employee());
        System.out.println(max.get());

        System.out.println("----------------------");
        Optional<Double> min = list.stream()
                .map(Employee::getSolary)
                .min(Double::compareTo);
        System.out.println(min.get());
    }

    /**
     * 归约
     * <p>
     * reduce(T identity, BinaryOperator<T> accumulator);
     * reduce(BinaryOperator<T> accumulator);
     */

    @Test
    public void test3() {
        List<Integer> lists = Arrays.asList(1, 2, 3, 4, 5, 6);

        Integer integer = lists.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(integer);

        System.out.println("-----------------------------------");

        Optional<Double> reduce = list.stream()
                .map(Employee::getSolary)
                .reduce(Double::sum);
        System.out.println(reduce.get());

    }

    /**
     * 收集
     * collect --收集---将流转换为其他的形式，接收一个Collector接口的实现，用于给stream中元素做汇总的方法
     */

    @Test
    public void test4() {
        List<String> collect = list.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());

        collect.forEach(System.out::println);
        System.out.println("-------------------------------");

        list.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet())
                .forEach(System.out::println);

        System.out.println("-----------------------------");

        list.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new))
                .forEach(System.out::println);

    }

    /**
     * 集合，将最终的结果放在一个集合中
     */
    @Test
    public void test5() {
        //总数
        Long collect = list.stream()
                .collect(Collectors.counting());
        System.out.println(collect);
        System.out.println("-------------------------------");


        //平均值
        Double aDouble = list.stream()
                .collect(Collectors.averagingDouble(Employee::getSolary));
        System.out.println(aDouble);
        System.out.println("----------------------");

        //总和
        Double collect1 = list.stream()
                .collect(Collectors.summingDouble(Employee::getSolary));
        System.out.println(collect1);
        System.out.println("------------------------------");

        //最大值
        Optional<Employee> collect2 = list.stream()
                .collect(Collectors.maxBy((e1, e2) -> e1.getSolary().compareTo(e2.getSolary())));
        System.out.println(collect2.get());
        System.out.println("------------------");

        //分组
        Map<Employee.Status, List<Employee>> map = list.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);


    }

    //分区
    @Test
    public void test6() {
        Map<Boolean, List<Employee>> collect = list.stream()
                .collect(Collectors.partitioningBy((e) -> e.getSolary() > 100));

        System.out.println(collect);
    }

    //求一些值的大小
    @Test
    public void test7() {
        DoubleSummaryStatistics collect = list.stream()
                .collect(Collectors.summarizingDouble(Employee::getSolary));
        System.out.println(collect.getAverage());
        System.out.println(collect.getCount());
        System.out.println(collect.getMax());
        System.out.println(collect.getMin());
        System.out.println(collect.getSum());

    }

    @Test
    public void test8() {
        String collect = list.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",", "--", "==="));
        System.out.println(collect);
    }

    @Test
    public void test9() {
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
        integerList.stream()
                .map((x) -> x * x).forEach(System.out::println);

    }


}
